package org.light.jpa.verb;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.JavascriptBlock;
import org.light.domain.JavascriptMethod;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.domain.Type;
import org.light.domain.Var;
import org.light.exception.ValidateException;
import org.light.generator.NamedS2SMStatementGenerator;
import org.light.generator.NamedS2SMStatementListGenerator;
import org.light.generator.NamedStatementGenerator;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;
import org.light.verb.FindFullInfoById;
import org.light.verb.SearchIndexedNamesByShortName;

public class Clone extends org.light.verb.Clone {

	@Override
	public Method generateDaoImplMethod() throws Exception{
		return null;
	}

	@Override
	public Method generateDaoMethodDefinition() throws Exception{
		return null;
	}

	@Override
	public Method generateServiceMethodDefinition() throws Exception{
		if (this.denied) return null;
		else {
			Method method = new Method();
			method.setStandardName("clone"+StringUtil.capFirst(this.domain.getStandardName()));
			method.setReturnType(new Type("Boolean"));
			method.setThrowException(true);
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken()+ "."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
			method.addSignature(new Signature(1,this.domain.getDomainId().getFieldName(),this.domain.getDomainId().getClassType()));
			return method;
		}
	}

	@Override
	public Method generateServiceImplMethod() throws Exception{
		if (this.denied) return null;
		else {
			Method method = new Method();
			method.setStandardName("clone"+StringUtil.capFirst(this.domain.getStandardName()));
			method.setReturnType(new Type("Boolean"));
			method.setThrowException(true);
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken()+ ".utils.StringUtil");
			method.addAdditionalImport(this.domain.getPackageToken()+ "."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
			method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDaoSuffix()+"."+this.domain.getStandardName()+"Dao");
			method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getServiceSuffix()+"."+this.domain.getStandardName()+"Service");
			method.addSignature(new Signature(1,this.domain.getDomainId().getLowerFirstFieldName(),this.domain.getDomainId().getClassType()));
			method.addMetaData("Override");
			
			FindFullInfoById find = new FindFullInfoById(this.domain);
			SearchIndexedNamesByShortName search = new SearchIndexedNamesByShortName(this.domain);
					
			List<Writeable> sList = new ArrayList<Writeable>();

			sList.add(new Statement(1000L,2,""+this.domain.getCapFirstDomainNameWithSuffix()+" "+this.domain.getLowerFirstDomainName()+" = dao."+StringUtil.lowerFirst(find.getVerbName())+"("+this.domain.getDomainId().getLowerFirstFieldName()+");"));
			sList.add(new Statement(2000L,2,""));
			sList.add(new Statement(3000L,2,"String "+this.domain.getDomainName().getLowerFirstFieldName()+" = "+this.domain.getLowerFirstDomainName()+".get"+this.domain.getDomainName().getCapFirstFieldName()+"();"));
			sList.add(new Statement(4000L,2,"String shortName = "+this.domain.getDomainName().getLowerFirstFieldName()+";"));
			sList.add(new Statement(5000L,2,"if ("+this.domain.getDomainName().getLowerFirstFieldName()+".contains(\"_\") && StringUtil.isInteger("+this.domain.getDomainName().getLowerFirstFieldName()+".substring("+this.domain.getDomainName().getLowerFirstFieldName()+".lastIndexOf('_')+1,"+this.domain.getDomainName().getLowerFirstFieldName()+".length()))) {"));
			sList.add(new Statement(6000L,3,"shortName = "+this.domain.getDomainName().getLowerFirstFieldName()+".substring(0,"+this.domain.getDomainName().getLowerFirstFieldName()+".lastIndexOf('_'));"));
			sList.add(new Statement(7000L,2,"}"));
			sList.add(new Statement(8000L,2,"List<"+this.domain.getCapFirstDomainNameWithSuffix()+"> names = dao."+StringUtil.lowerFirst(search.getVerbName())+"(shortName);"));
			sList.add(new Statement(9000L,2,"int indexNum = 1;"));
			sList.add(new Statement(10000L,2,"for ("+this.domain.getCapFirstDomainNameWithSuffix()+" "+this.domain.getLowerFirstDomainName()+"0:names) {"));
			sList.add(new Statement(11000L,3,"String _name = "+this.domain.getLowerFirstDomainName()+"0.get"+this.domain.getDomainName().getCapFirstFieldName()+"();"));
			sList.add(new Statement(12000L,3,"if (_name.contains(\"_\") && StringUtil.isInteger(_name.substring(_name.lastIndexOf('_')+1,_name.length()))) {"));
			sList.add(new Statement(14000L,4,"int index = Integer.valueOf(_name.substring(_name.lastIndexOf('_')+1,_name.length()));"));
			sList.add(new Statement(15000L,4,"if (index >= indexNum) {"));
			sList.add(new Statement(16000L,5,"indexNum = index + 1;"));
			sList.add(new Statement(17000L,4,"}"));
			sList.add(new Statement(18000L,3,"}"));
			sList.add(new Statement(19000L,2,"}"));
			sList.add(new Statement(20000L,2,"String indexName = shortName + \"_\" + indexNum;"));
			sList.add(new Statement(21000L,2, this.domain.getCapFirstDomainNameWithSuffix()+" "+this.domain.getLowerFirstDomainName()+"1 = "+this.domain.getLowerFirstDomainName()+".clone();"));
			sList.add(new Statement(22000L,2,""+this.domain.getLowerFirstDomainName()+"1.set"+this.domain.getDomainId().getCapFirstFieldName()+"(null);"));
			sList.add(new Statement(23000L,2,""+this.domain.getLowerFirstDomainName()+"1.set"+this.domain.getDomainName().getCapFirstFieldName()+"(indexName);"));
			sList.add(new Statement(24000L,2,"add"+this.domain.getCapFirstDomainName()+"("+this.domain.getLowerFirstDomainName()+"1);"));
			sList.add(new Statement(25000L,2,"return true;"));			
			method.setMethodStatementList(WriteableUtil.merge(sList));
			return method;
		}
	}

	public Clone(){
		super();
		this.setLabel("克隆");
	}
	
	public Clone(Domain domain) throws ValidateException{
		super();
		this.domain = domain;
		this.denied = domain.isVerbDenied("Clone");
		this.setVerbName("Clone"+StringUtil.capFirst(this.domain.getStandardName()));
		this.setLabel("克隆");
		if  (domain.getLanguage().equalsIgnoreCase("english"))  this.setLabel("Clone");
	}
}
